package cn.cleanarch.infra.idp.s3.controller;

import cn.cleanarch.infra.idp.s3.domain.entity.S3Config;
import cn.cleanarch.infra.idp.s3.service.S3AuditService;
import cn.cleanarch.infra.idp.s3.service.S3ConfigService;
import cn.cleanarch.infra.idp.s3.service.S3Service;
import cn.cleanarch.infra.idp.uaa.business.service.UserService;
import cn.cleanarch.infra.idp.uaa.core.domain.entity.User;
import cn.cleanarch.infra.idp.uaa.core.util.LoginSessionTool;
import cn.cleanarch.infra.idp.web.model.Result;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;

/**
 * S3文件上传控制器
 */
@RestController
@RequestMapping("/api/upload")
public class S3UploadController {

    @Autowired
    private S3ConfigService s3ConfigService;

    @Autowired
    private S3Service s3Service;

    @Autowired
    private S3AuditService s3AuditService;

    @Autowired
    private UserService userService;

    /**
     * 根据业务类型上传文件到S3
     */
    @PostMapping("/{businessType}")
    public Result uploadFile(
            @PathVariable("businessType") String businessType,
            @RequestParam("file") MultipartFile file,
            HttpServletRequest request) {

        long startTime = System.currentTimeMillis();

        if (file.isEmpty()) {
            return Result.fail("请选择要上传的文件");
        }

        // 根据业务类型获取S3配置
        S3Config config = s3ConfigService.getByBusinessType(businessType);
        if (config == null) {
            return Result.fail("未找到对应的S3配置");
        }

        if (!config.getEnabled()) {
            return Result.fail("该S3配置已被禁用");
        }

        try {
            // 生成对象键（文件在S3中的路径）
            String objectKey = generateObjectKey(businessType, file.getOriginalFilename());

            // 获取当前用户信息
            Long userId = LoginSessionTool.getCurrentUser().getUserId();
            User user = userService.getUserById(userId);
            String username = user.getUsername();

            // 上传文件到S3
            String fileUrl = s3Service.uploadFile(config, file, objectKey);

            long endTime = System.currentTimeMillis();
            long executionTime = endTime - startTime;

            // 记录审计日志
            s3AuditService.logUploadOperation(
                    userId,
                    username,
                    businessType,
                    file.getOriginalFilename(),
                    file.getSize(),
                    objectKey,
                    config.getId(),
                    getClientIpAddress(request),
                    request.getHeader("User-Agent"),
                    executionTime,
                    "SUCCESS",
                    null
            );

            // 返回上传结果
            Map<String, Object> result = new HashMap<>();
            result.put("fileUrl", fileUrl);
            result.put("objectKey", objectKey);
            result.put("fileName", file.getOriginalFilename());
            result.put("fileSize", file.getSize());
            result.put("contentType", file.getContentType());

            return Result.data(result);
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            long executionTime = endTime - startTime;

            // 获取当前用户信息
            Long userId = LoginSessionTool.getCurrentUser().getUserId();
            User user = userService.getUserById(userId);
            String username = user.getUsername();

            // 记录审计日志（失败）
            s3AuditService.logUploadOperation(
                    userId,
                    username,
                    businessType,
                    file.getOriginalFilename(),
                    file.getSize(),
                    null,
                    config.getId(),
                    getClientIpAddress(request),
                    request.getHeader("User-Agent"),
                    executionTime,
                    "FAILED",
                    e.getMessage()
            );

            return Result.fail("文件上传失败: " + e.getMessage());
        }
    }

    /**
     * 生成S3对象键
     */
    private String generateObjectKey(String businessType, String originalFilename) {
        // 使用时间戳和业务类型生成唯一对象键
        long timestamp = System.currentTimeMillis();
        String extension = "";
        int lastDotIndex = originalFilename.lastIndexOf('.');
        if (lastDotIndex > 0) {
            extension = originalFilename.substring(lastDotIndex);
        }
        return String.format("%d%s", timestamp, extension);
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIpAddress(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
            // X-Forwarded-For可能包含多个IP地址，取第一个
            int index = xForwardedFor.indexOf(',');
            if (index != -1) {
                return xForwardedFor.substring(0, index);
            } else {
                return xForwardedFor;
            }
        }

        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
            return xRealIp;
        }

        return request.getRemoteAddr();
    }
}